/*
 * (C) APUE
 * Read or write the assigned bytes. 
 */
#include "apue.h"

/* read n byte from a given descriptors */
ssize_t readn(int filedes, void *buf, size_t nbytes)
{
	size_t nleft;
	ssize_t nread;
	nleft = nbytes;
	while (nleft > 0)
	{
		if ((nread = read(filedes, buf, nleft)) < 0)
		{
			if (nleft == nbytes)
				return (-1); /* error: first read error */
			else
				break; /* already have some read data, then return the data bytes have read */
		}
		else if (nread == 0) /* EOF */
			break;

		nleft -= nread;
		buf += nread;
	}
	return (nbytes - nleft);	/* data bytes have already read */
}

ssize_t writen(int filedes, void *buf, size_t nbytes)
{
	size_t nleft;
	ssize_t nwrite;
	nleft = nbytes;
	while (nleft > 0)
	{
		if ((nwrite = write(filedes, buf, nleft)) < 0)
		{
			if (nleft == nbytes)
				return (-1); /* error: first read error */
			else
				break; /* already have some read data, then return the data bytes have read */
		}
		else if (nwrite == 0) /* EOF */
			break;

		nleft -= nwrite;
		buf += nwrite;
	}
	return (nbytes - nleft);	/* data bytes have already read */
}
